/*
 * UMLSynch plugin for Eclipse
 * http://umlsynch.googlecode.com
 *
 * Copyright 2008-2010, Evgeny Alexeyev
 * Licensed under the EPL - v1.0
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */

package com.googlecode.umlsynch.VPOperationServer;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

public class VPOperationServerCaller implements IVPOperationServer{

	private Socket clientSocket;
	private ObjectOutputStream outObjStream;
	private ObjectInputStream inObjStream;
	private static VPOperationServerCaller singletone = null;
	
	private MessageConsole myConsole;
	private MessageConsoleStream out;
	
	public static VPOperationServerCaller instance() {
		if (singletone == null)
			singletone = new VPOperationServerCaller();
		return singletone;
	}
	VPOperationServerCaller () {
	  myConsole = findConsole("my console");
	  out = myConsole.newMessageStream();	
	}
	
	private MessageConsole findConsole(String name) {
	      ConsolePlugin plugin = ConsolePlugin.getDefault();
	      IConsoleManager conMan = plugin.getConsoleManager();
	      IConsole[] existing = conMan.getConsoles();
	      for (int i = 0; i < existing.length; i++)
	          if (name.equals(existing[i].getName()))
	             return (MessageConsole) existing[i];
	      //no console found, so create a new one
	      MessageConsole myConsole = new MessageConsole(name, null);
	      conMan.addConsoles(new IConsole[]{myConsole});
	      return myConsole;
	}
	
	@Override
	public void CreateClassOnDiagram(VPSDEClassDescriptor desc, VPPoint pt) {
		// do nothing if descriptor is null
		if (desc == null)
			return;
		
		try { // Open client socket port 3129 and read/write objects			
		  clientSocket = new Socket("localhost", 3129);
		  outObjStream = new ObjectOutputStream(clientSocket.getOutputStream());
		}
		catch(Exception e) {
          out.println("init error: "+e);
        } // Print nothing, because system.out doesn't work at runtime mode

		try {
			// Send the RPC method name 
			outObjStream.writeObject(new String("CreateClassOnDiagram"));

			// Send the object name 
			outObjStream.writeObject(new String("VPSDEClassDescriptor"));
			outObjStream.writeObject(desc);

			outObjStream.writeObject(new String("VPPoint"));
			outObjStream.writeObject(pt);

            // Don't need any feedback
			clientSocket.close();
		} catch (IOException ex ){
			out.println("IOException");
		}
	}

	@Override
	public void CreatePacketOnDiagram(VPSDEPacketDescriptor desc, VPPoint pt) {
		if (desc == null)
			return;
		
		try	{
		  clientSocket = new Socket("localhost", 3129);
		  outObjStream = new ObjectOutputStream(clientSocket.getOutputStream());
		  inObjStream = new ObjectInputStream(clientSocket.getInputStream());
		}
		catch(Exception e) 	{
		  out.println("init error: "+e);
		}
		
		try {
			outObjStream.writeObject(new String("CreatePacketOnDiagram"));
			outObjStream.writeObject(new String("VPSDEPacketDescriptor"));
			outObjStream.writeObject(desc);
			outObjStream.writeObject(new String("VPPoint"));
			outObjStream.writeObject(pt);

			clientSocket.close();
		} catch (IOException ex ){
			out.println("IOException");
		}		
	}

	@Override
	public VPWorkingAreaDescriptor GetWorkingArea() {
		try {
  		  clientSocket = new Socket("localhost", 3129);
		  outObjStream = new ObjectOutputStream(clientSocket.getOutputStream());
		  inObjStream = new ObjectInputStream(clientSocket.getInputStream());
		}
		catch(Exception e) {
		  out.println("init error: "+e);
		}

		String data;  
		try {
		  outObjStream.writeObject(new String("GetWorkingArea"));
		  
          data = (String) inObjStream.readObject();
		  if (data.equals("VPWorkingAreaDescriptor")) {
			  VPWorkingAreaDescriptor desc = (VPWorkingAreaDescriptor)inObjStream.readObject();
			  out.println("VPWorkingAreaDescriptor");
			  return desc;
		  } else if (data.equals("VPWorkingAreaDescriptorNull")) {
			  out.println("VPWorkingAreaDescriptorNull");
              return null;				
		  }

		  clientSocket.close();
		} catch (IOException ex ){
			out.println("IOException " + ex.getMessage());
		}
		catch (ClassNotFoundException e) {
		  out.println("ClassNotFoundException " + e.getMessage());
		}
		
		out.println("Null");
		return null;
	}
	@Override
	public void CreateEnumOnDiagram(VPSDEEnumDescriptor desc, VPPoint pt) {
		if (desc == null)
			return;
		
		try	{
		  clientSocket = new Socket("localhost", 3129);
		  outObjStream = new ObjectOutputStream(clientSocket.getOutputStream());
		  inObjStream = new ObjectInputStream(clientSocket.getInputStream());
		}
		catch(Exception e) 	{
		  out.println("init error: "+e);
		}
		
		try {
			outObjStream.writeObject(new String("CreateEnumOnDiagram"));
			outObjStream.writeObject(new String("VPSDEEnumDescriptor"));
			outObjStream.writeObject(desc);
			outObjStream.writeObject(new String("VPPoint"));
			outObjStream.writeObject(pt);

			clientSocket.close();
		} catch (IOException ex ){
			out.println("IOException");
		}	
	}
}
